package testing;

import static org.junit.Assert.*;

import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;

import poker.*;

public class TestHandPowerRating   
{
	@Test
	public void compareHands()
	{
		Card[] straightFlush = {new Card('H', 14), new Card('H', 10), new Card('H', 11), new Card('H',12), new Card('S', 9), new Card('H', 13)};
		Card[] straightFlushs = {new Card('H', 9), new Card('H', 10), new Card('H', 11), new Card('H',12), new Card('S', 9), new Card('H', 13)};
		Card[] four = {new Card('S', 14), new Card('D', 14), new Card('C', 14), new Card('C',13), new Card('D', 5), new Card('H', 14)};
		Card[] fours = {new Card('S', 14), new Card('D', 14), new Card('C', 14), new Card('C',6), new Card('D', 5), new Card('H', 14)};
		Card[] house = {new Card('S', 2), new Card('C', 2), new Card('D', 2), new Card('H',14), new Card('S', 14), new Card('D', 10)};
		Card[] houses = {new Card('S', 2), new Card('C', 2), new Card('D', 2), new Card('H',13), new Card('S', 13), new Card('D', 10)};
		Card[] flush = {new Card('S', 4), new Card('S', 10), new Card('S', 7), new Card('S',6), new Card('S', 5)};
		Card[] flushs = {new Card('S', 3), new Card('S', 10), new Card('S', 7), new Card('S',6), new Card('S', 5)};
		Card[] straight = {new Card('S', 14), new Card('D', 13), new Card('S', 12), new Card('C',11), new Card('D', 10), new Card('D', 11), new Card('D', 4)};
		Card[] straights = {new Card('S', 2), new Card('D', 13), new Card('S', 5), new Card('C',14), new Card('D', 3), new Card('D', 11), new Card('D', 4)};
		Card[] tress  = {new Card('S', 14), new Card('D', 14), new Card('C', 14), new Card('C',6), new Card('D', 5), new Card('D', 11)};
		Card[] tresss  = {new Card('S', 14), new Card('D', 14), new Card('C', 14), new Card('C',6), new Card('D', 5), new Card('D', 10)};
		Card[] two = {new Card('S', 2), new Card('D', 2), new Card('S', 7), new Card('C',7), new Card('H', 5), new Card('D', 11)};
		Card[] twos = {new Card('S', 2), new Card('D', 2), new Card('S', 7), new Card('C',7), new Card('H', 5), new Card('D', 10)};
		Card[] one = {new Card('S', 10), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		Card[] ones = {new Card('S', 10), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 4)};
		Card[] hand = {new Card('S', 14), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		Card[] hand1 = {new Card('S', 14), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 4)};
		
		assertEquals(1, HandPowerRating.compare(straightFlush, four));
		assertEquals(0, HandPowerRating.compare(straightFlush, straightFlush));
		assertEquals(1, HandPowerRating.compare(straightFlush, straightFlushs));

		assertEquals(1, HandPowerRating.compare(four, house));
		assertEquals(0, HandPowerRating.compare(four, four));
		assertEquals(1, HandPowerRating.compare(four, fours));

		assertEquals(1, HandPowerRating.compare(house, flush));
		assertEquals(0, HandPowerRating.compare(house, house));
		assertEquals(1, HandPowerRating.compare(house, houses));

		assertEquals(1, HandPowerRating.compare(flush, straight));
		assertEquals(0, HandPowerRating.compare(flush, flush));
		assertEquals(1, HandPowerRating.compare(flush, flushs));

		assertEquals(1, HandPowerRating.compare(straight, tress));
		assertEquals(0, HandPowerRating.compare(straight, straight));
		assertEquals(1, HandPowerRating.compare(straight, straights));

		assertEquals(1, HandPowerRating.compare(tress, two));
		assertEquals(0, HandPowerRating.compare(tress, tress));
		assertEquals(1, HandPowerRating.compare(tress, tresss));

		assertEquals(1, HandPowerRating.compare(two, one));
		assertEquals(0, HandPowerRating.compare(two, two));
		assertEquals(1, HandPowerRating.compare(two, twos));

		assertEquals(1, HandPowerRating.compare(one, hand));
		assertEquals(0, HandPowerRating.compare(one, one));
		assertEquals(1, HandPowerRating.compare(one, ones));
		
		assertEquals(1, HandPowerRating.compare(hand, hand1));
	}
	
	@Test
	public void isStraightFlush()
	{
		Card[] hand = {new Card('H', 14), new Card('H', 10), new Card('H', 11), new Card('H',12), new Card('S', 9), new Card('H', 13)};
		assertEquals("Expected straight flush but wasn�t", 9 ,HandPowerRating.rate(hand)[0]);
		assertEquals(14, HandPowerRating.rate(hand)[1]);
		
		Card[] hand2 = {new Card('H', 13), new Card('H', 10), new Card('S',11), new Card('H', 12), new Card('H', 9), new Card('S', 3),};
		assertThat(9, not(HandPowerRating.rate(hand2)[0]));
		
		Card[] hand3 = {new Card('C', 13), new Card('C', 9), new Card('C',10), new Card('C', 12), new Card('C', 11)}; 
		assertEquals("Expected straight flush but wasn�t", 9 ,HandPowerRating.rate(hand3)[0]);
		assertEquals(13, HandPowerRating.rate(hand3)[1]);
	
		Card[] hand4 = {new Card('C', 14), new Card('C', 2), new Card('C', 5), new Card('C', 3), new Card('C', 4), new Card('D', 6)}; 
		assertEquals("Expected straight flush but wasn�t", 9, HandPowerRating.rate(hand4)[0]);
		assertEquals(5, HandPowerRating.rate(hand4)[1]);	
		
		Card[] hand5 = {new Card('C', 14), new Card('C', 2), new Card('C', 5), new Card('C', 3), new Card('C', 4), new Card('C', 13)}; 
		assertEquals("Expected straight flush but wasn�t", 9, HandPowerRating.rate(hand5)[0]);
		assertEquals(5, HandPowerRating.rate(hand5)[1]);	
	}
		
	@Test
	public void isFourOfAKind()
	{
		Card[] hand = {new Card('S', 3), new Card('D', 4), new Card('S', 7), new Card('C',6), new Card('D', 5)};
		assertThat(8, not(HandPowerRating.rate(hand)[0]));
		
		Card[] hand2 = {new Card('S', 14), new Card('D', 14), new Card('C', 14), new Card('C',6), new Card('D', 5), new Card('H', 14)};
		assertEquals("Expected four of a kind but wasn't.", 8, HandPowerRating.rate(hand2)[0]);
		assertEquals(14, HandPowerRating.rate(hand2)[1]);
		assertEquals(6, HandPowerRating.rate(hand2)[2]);
		
		Card[] hand3 = {new Card('S', 2), new Card('D', 4), new Card('S', 7), new Card('C',2), new Card('D', 2), new Card('H', 2), new Card('D', 10)};
		assertEquals("Expected four of a kind but wasn't.", 8, HandPowerRating.rate(hand3)[0]);
		assertEquals(2, HandPowerRating.rate(hand3)[1]);		
		assertEquals(10, HandPowerRating.rate(hand3)[2]);
	}
	
	@Test
	public void isFullHouse()
	{
		Card[] hand = {new Card('S', 2), new Card('C', 2), new Card('D', 2), new Card('H',13), new Card('S', 13), new Card('D', 10)};
		assertEquals("Expected full house but wasn't.", 7, HandPowerRating.rate(hand)[0]);
		assertEquals(2, HandPowerRating.rate(hand)[1]);
		assertEquals(13, HandPowerRating.rate(hand)[2]);
		
		Card[] hand2 = {new Card('D', 13), new Card('D', 12), new Card('S', 5), new Card('C',13), new Card('H', 13), new Card('H', 14)};
		assertThat(7, not(HandPowerRating.rate(hand2)[0]));
				
		Card[] hand3 = {new Card('S', 2), new Card('H',13), new Card('C', 13), new Card('D', 2), new Card('S', 13)};
		assertEquals("Expected full house but wasn't.", 7, HandPowerRating.rate(hand3)[0]);
		assertEquals(13, HandPowerRating.rate(hand3)[1]);
		assertEquals(2, HandPowerRating.rate(hand3)[2]);			
	}
	
	@Test
	public void isFlush()
	{
		Card[] hand4 = { new Card('s', 11), new Card('d', 2), new Card('d', 13), new Card('d', 7), new Card('d', 14), new Card('d', 10) };
		assertEquals(6, HandPowerRating.rate(hand4)[0]);
		
		Card[] hand = {new Card('S', 3), new Card('S', 10), new Card('S', 7), new Card('S',6), new Card('S', 5)};
		assertEquals("Expected a flush but wasn't.", 6, HandPowerRating.rate(hand)[0]);
		assertEquals(10, HandPowerRating.rate(hand)[1]);
		assertEquals(7, HandPowerRating.rate(hand)[2]);
		assertEquals(6, HandPowerRating.rate(hand)[3]);
		assertEquals(5, HandPowerRating.rate(hand)[4]);
		assertEquals(3, HandPowerRating.rate(hand)[5]);
		
		Card[] hand2 = {new Card('C', 3), new Card('C', 4), new Card('C', 10), new Card('H', 12), new Card('D', 14), new Card('C', 9), new Card('H', 9)};
		assertThat(6, not(HandPowerRating.rate(hand2)[0]));

		Card[] hand3 = {new Card('S', 10), new Card('S', 2), new Card('S', 7), new Card('C', 10), new Card('S',6), new Card('S', 5)};
		assertEquals("Expected a flush but wasn't.", 6, HandPowerRating.rate(hand3)[0]);
		assertEquals(10, HandPowerRating.rate(hand3)[1]);
		assertEquals(7, HandPowerRating.rate(hand3)[2]);
		assertEquals(6, HandPowerRating.rate(hand3)[3]);
		assertEquals(5, HandPowerRating.rate(hand3)[4]);
		assertEquals(2, HandPowerRating.rate(hand3)[5]);		
	}
		
	@Test
	public void isStraight()
	{
		Card[] s = {new Card('s', 2), new Card('s', 7), new Card('c', 8),new Card('s',9 ), new Card('c', 14), new Card('h', 14), new Card('c',6 )};
		assertThat(5, not(HandPowerRating.rate(s)[0]));
		
		Card[] straight = {new Card('S', 14), new Card('D', 13), new Card('S', 12), new Card('C',11), new Card('D', 10), new Card('D', 11), new Card('D', 4)};
		assertEquals("Expected a straight but wasn't.", 5, HandPowerRating.rate(straight)[0]);
		assertEquals(14, HandPowerRating.rate(straight)[1]);
		
		Card[] hand4 = {new Card('S', 2), new Card('D', 13), new Card('S', 5), new Card('C',14), new Card('D', 3), new Card('D', 11), new Card('D', 4)};
		assertEquals("Expected a straight but wasn't.", 5, HandPowerRating.rate(hand4)[0]);
		assertEquals(5, HandPowerRating.rate(hand4)[1]);
		
		Card[] hand = {new Card('S', 3), new Card('D', 4), new Card('S', 7), new Card('C',6), new Card('D', 5)};
		assertEquals("Expected a straight but wasn't.", 5, HandPowerRating.rate(hand)[0]);
		assertEquals(7, HandPowerRating.rate(hand)[1]);
		
		Card[] hand2 = {new Card('S', 3), new Card('D', 3), new Card('S', 7), new Card('C',6), new Card('D', 5), new Card('D', 2)};
		assertThat(5, not(HandPowerRating.rate(hand2)[0]));
		
		Card[] hand3 = {new Card('S', 2), new Card('D', 13), new Card('S', 14), new Card('C',6), new Card('D', 12), new Card('D', 11), new Card('D', 10)};
		assertEquals("Expected a straight but wasn't.", 5, HandPowerRating.rate(hand3)[0]);
		assertEquals(14, HandPowerRating.rate(hand3)[1]);
	}
	
	@Test
	public void isThreeOfAKind()
	{
		Card[] hand = {new Card('S', 10), new Card('D', 4), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		assertThat(4, not(HandPowerRating.rate(hand)[0]));
		
		Card[] hand2 = {new Card('S', 14), new Card('D', 14), new Card('C', 14), new Card('C',6), new Card('D', 5), new Card('D', 10)};
		assertEquals("Expected a three of a kind but wasn't.", 4, HandPowerRating.rate(hand2)[0]);
		assertEquals(14, HandPowerRating.rate(hand2)[1]);
		assertEquals(10, HandPowerRating.rate(hand2)[2]);
		assertEquals(6, HandPowerRating.rate(hand2)[3]);		
		
		Card[] hand3 = {new Card('S', 2), new Card('D', 4), new Card('S', 7), new Card('C',2), new Card('D', 2), new Card('H', 5), new Card('D', 10)};
		assertEquals("Expected a three of a kind but wasn't.", 4, HandPowerRating.rate(hand3)[0]);
		assertEquals(2, HandPowerRating.rate(hand3)[1]);
		assertEquals(10, HandPowerRating.rate(hand3)[2]);	
		assertEquals(7, HandPowerRating.rate(hand3)[3]);
	}

	@Test
	public void isTwoPair()
	{
		Card[] hand = {new Card('S', 10), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		assertThat(3, not(HandPowerRating.rate(hand)[0]));
		
		Card[] hand2 = {new Card('S', 2), new Card('D', 2), new Card('S', 7), new Card('C',7), new Card('H', 5), new Card('D', 10)};
		assertEquals("Expected a two pairs but wasn't.", 3, HandPowerRating.rate(hand2)[0]);
		assertEquals(7, HandPowerRating.rate(hand2)[1]);
		assertEquals(2, HandPowerRating.rate(hand2)[2]);	
		assertEquals(10, HandPowerRating.rate(hand2)[3]);	
		
		Card[] hand3 = {new Card('S', 14),  new Card('C', 5), new Card('D', 14), new Card('C',7), new Card('H', 5), new Card('D', 11)};
		assertEquals("Expected a two pairs but wasn't.", 3, HandPowerRating.rate(hand3)[0]);
		assertEquals(14, HandPowerRating.rate(hand3)[1]);
		assertEquals(5, HandPowerRating.rate(hand3)[2]);
		assertEquals(11, HandPowerRating.rate(hand3)[3]);		
	}
	
	@Test
	public void isOnePair()
	{
		Card[] hand = {new Card('S', 10), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		assertEquals("Expected a one pair but wasn't.", 2, HandPowerRating.rate(hand)[0]);
		assertEquals(10, HandPowerRating.rate(hand)[1]);
		assertEquals(11, HandPowerRating.rate(hand)[2]);
		assertEquals(7, HandPowerRating.rate(hand)[3]);
		assertEquals(5, HandPowerRating.rate(hand)[4]);
		
		Card[] hand2 = {new Card('S', 14), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		assertThat(2, not(HandPowerRating.rate(hand2)[0]));
	}
	
	@Test
	public void isHighCard()
	{
		Card[] hand = {new Card('S', 14), new Card('D', 10), new Card('S', 7), new Card('C',11), new Card('D', 5)};
		assertEquals("Expected a high card but wasn't.", 1, HandPowerRating.rate(hand)[0]);
	}
	
}
